import tkinter as tk
from tkinter import ttk
import time
from pynput import keyboard
import pyautogui

from scrollable_widgets import create_scrollable_text
from utils import create_centered_window


class ManualExecutor:
    def __init__(self, steps, main_window):
        self.steps = steps
        self.main_window = main_window

        # 步骤函数列表
        self.step_functions = []
        self.create_step_functions()

        # 执行状态
        self.current_step = 0

        # UI组件
        self.progress_bar = None
        self.log_area = None
        self.step_label = None

        # 键盘监听器
        self.keyboard_listener = None

        self.root = create_centered_window(title="手动执行器", width=900, height=700, window_type='top',
                                           parent=main_window)

        # 添加窗口关闭协议处理
        self.root.protocol("WM_DELETE_WINDOW", self.back_to_main)

        # 创建UI
        self.create_ui()

    def create_step_functions(self):
        """根据步骤数据创建可执行的函数列表"""
        for step_data in self.steps:
            # 每次循环都创建新的函数
            def step_func(data=step_data):  # 使用默认参数避免闭包问题
                # 根据步骤类型执行不同的操作
                step_type = data.get('type')
                if step_type == "click":
                    pyautogui.click(data['x'], data['y'])
                elif step_type == "double_click":
                    pyautogui.doubleClick(data['x'], data['y'])
                elif step_type == "input":
                    pyautogui.write(data['value'])
                elif step_type == "enter":
                    pyautogui.press('enter')
                else:
                    print(f"未知的步骤类型: {step_type}")

            # 为每个函数设置属性
            step_func.step_data = step_data
            self.step_functions.append(step_func)

    def create_ui(self):
        """设置用户界面"""
        # 主框架
        main_frame = ttk.Frame(self.root, padding=20)
        main_frame.pack(fill=tk.BOTH, expand=True)

        # 步骤显示框架
        step_frame = ttk.LabelFrame(main_frame, text="执行进度", padding="10")
        step_frame.pack(fill=tk.X, pady=(0, 10))

        self.step_label = ttk.Label(step_frame, text="步骤: 0/0")
        # 在可用空间内左对齐
        self.step_label.pack(anchor=tk.W)

        self.progress_bar = ttk.Progressbar(step_frame, mode='determinate')
        self.progress_bar.pack(fill=tk.X, pady=(5, 0))
        self.progress_bar['maximum'] = len(self.steps)

        # 控制按钮框架
        button_frame = ttk.Frame(main_frame)
        button_frame.pack(fill=tk.X, pady=(0, 10))

        # 按钮容器框架
        buttons_container = ttk.Frame(button_frame)
        buttons_container.pack()

        # 手动模式下只保留返回主窗口按钮
        back_button = ttk.Button(buttons_container, text="返回主窗口", command=self.back_to_main)
        back_button.pack()

        # 添加键盘操作提示
        hint_frame = ttk.Frame(button_frame)
        hint_frame.pack(pady=(10, 0))

        hint_label = ttk.Label(hint_frame, text="键盘操作提示:", foreground="blue",
                               font=("微软雅黑", 10, "bold"))
        hint_label.pack()

        left_hint = ttk.Label(hint_frame, text="← (左箭头键): 上一步", foreground="blue")
        left_hint.pack()

        right_hint = ttk.Label(hint_frame, text="→ (右箭头键): 下一步", foreground="blue")
        right_hint.pack()

        up_hint = ttk.Label(hint_frame, text="↑ (上箭头键): 重置到第一步", foreground="blue")
        up_hint.pack()

        # 日志区域
        log_frame = ttk.LabelFrame(main_frame, text="执行日志", padding="10")
        log_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 10))

        # 增加日志区域高度
        self.log_area = create_scrollable_text(log_frame, height=20, state=tk.DISABLED)
        self.log_area.pack(fill=tk.BOTH, expand=True)

        # 初始化UI状态
        self.update_progress()

        # 绑定全局键盘事件
        self.register_global_hotkeys()

    def register_global_hotkeys(self):
        """注册全局键盘热键"""

        def on_press(key):
            # 处理特殊按键
            if key == keyboard.Key.left:
                self.prev_step()
            elif key == keyboard.Key.right:
                self.next_step()
            elif key == keyboard.Key.up:
                self.reset_to_first_step()
            # 普通按键会被忽略，无需特殊处理

        # 创建并启动监听器
        self.keyboard_listener = keyboard.Listener(on_press=on_press)
        self.keyboard_listener.start()
        self.log_message("已注册全局键盘热键:")
        self.log_message("  ← (左箭头键): 上一步")
        self.log_message("  → (右箭头键): 下一步")
        self.log_message("  ↑ (上箭头键): 重置到第一步")

    def update_progress(self):
        """更新步骤标签"""
        self.step_label.config(
            text=f"步骤: {self.current_step}/{len(self.steps)}")
        self.progress_bar['value'] = self.current_step
        # 强制进度条更新
        self.progress_bar.update_idletasks()

    def log_message(self, message: str):
        """记录日志信息"""
        if self.log_area:  # 只有当log_area存在时才记录日志
            self.log_area.config(state=tk.NORMAL)
            timestamp = time.strftime("%H:%M:%S", time.localtime())
            self.log_area.insert(tk.END, f"[{timestamp}] {message}\n")
            self.log_area.see(tk.END)
            self.log_area.config(state=tk.DISABLED)

    def prev_step(self):
        """执行上一步"""
        if self.current_step > 0:
            self.current_step -= 1
            self.execute_current_step()
            self.update_progress()

    def next_step(self):
        """执行下一步"""
        if self.current_step < len(self.steps):
            self.execute_current_step()
            self.current_step += 1
            self.update_progress()

    def reset_to_first_step(self):
        """重置到第一步"""
        self.current_step = 0
        self.update_progress()
        self.log_message("已重置到第一步")

    def execute_current_step(self):
        """执行当前步骤"""
        try:
            step_func = self.step_functions[self.current_step]
            # 获取步骤名称（如果可用）
            step_name = step_func.step_data.get('name', '未知步骤')
            self.log_message(f"执行步骤 {self.current_step + 1}: {step_name}")
            step_func()
        except Exception as e:
            self.log_message(f"执行步骤 {self.current_step + 1} 时出错: {str(e)}")

    def back_to_main(self):
        """返回主窗口"""
        # 注销全局热键
        if self.keyboard_listener:
            self.keyboard_listener.stop()
        # 销毁执行器窗口
        self.root.destroy()
        # 显示主窗口
        self.main_window.deiconify()
